package mark.miniboard;

import java.util.Timer;
import java.util.TimerTask;

import android.inputmethodservice.InputMethodService;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.InputConnection;

/** Interfaces between the MiniboardView and the Android OS */
public class Miniboard extends InputMethodService {

    /** the lower case QUERTY keyboard layout */
    private final static String[][] QUERTY = new String[][]{
        {"q", "a", "z"},
        {"w", "s", "x"},
        {"e", "d", "c"},
        {"r", "f", "v"},
        {"t", "g", "b"},
        {"123", " ", "Space"},
        {"y", "h", "n"},
        {"u", "j", "m"},
        {"i", "k", ","},
        {"o", "l", "."},
        {"p", ";", "/"},
        {"Delete", "Enter", "Shift"},
    };

    /** the upper case QUERTY keyboard layout */
    private final static String[][] CAPS = new String[][]{
        {"Q", "A", "Z"},
        {"W", "S", "X"},
        {"E", "D", "C"},
        {"R", "F", "V"},
        {"T", "G", "B"},
        {"123", " ", "Space"},
        {"Y", "H", "N"},
        {"U", "J", "M"},
        {"I", "K", "<"},
        {"O", "L", ">"},
        {"P", ":", "?"},
        {"Delete", "Enter", "Shift"},
    };

    /** a keyboard layout consisting of numbers and symbols */
    private final static String[][] SYMBOLS = new String[][]{
        {"!", "1", "`"},
        {"@", "2", "-"},
        {"#", "3", "="},
        {"$", "4", "["},
        {"%", "5", "]"},
        {"ABC", " ", "Space"},
        {"^", "6", "\\"},
        {"&", "7", "'"},
        {"*", "8", ","},
        {"(", "9", "."},
        {")", "0", "/"},
        {"Delete", "Enter", "Shift"},
    };

    /** a keyboard layout consisting of numbers and symbols */
    private final static String[][] CAPITAL_SYMBOLS = new String[][]{
        {"!", "1", "~"},
        {"@", "2", "_"},
        {"#", "3", "+"},
        {"$", "4", "{"},
        {"%", "5", "}"},
        {"ABC", " ", "Space"},
        {"^", "6", "|"},
        {"&", "7", "\""},
        {"*", "8", "<"},
        {"(", "9", ">"},
        {")", "0", "?"},
        {"Delete", "Enter", "Shift"},
    };
    
    /** the view and input handler */
    private MiniboardView view;
    
    /** the key that was most recently pressed */
    private String pressedKey;
    
    /** the timer used to create repeat key presses */
    private Timer timer = new Timer();
    
    /** the timer task used to create repeat key presses */
    private TimerTask repeatTask;

    /**
     * Creates and initializes the MiniboardView
     * @return the newly created MiniboardView
     */
    @Override public View onCreateInputView() {
        
        view = (MiniboardView) getLayoutInflater().inflate(
                R.layout.input, null);
        view.setKeys(QUERTY);
        return view;
    }

    /**
     * Overridden to prevent full screen mode
     * @return always false
     */
    @Override
    public boolean onEvaluateFullscreenMode() {
        return false;
    }

    /**
     * Called by the view when a key press event has been registered
     * @param key the key that has been pressed
     */
    public void onPress(final String key) {

        if (!key.equals(pressedKey)) {
            
            if (repeatTask != null) {
                repeatTask.cancel();
                repeatTask = null;
                timer.purge();
            }
            
            if ("Delete".equals(key)) {
                repeatTask = new TimerTask() {
                    @Override
                    public void run() {
                        processKey(key);
                    }
                };
                timer.schedule(repeatTask, 500, 100);
            }
            pressedKey = key;
        }
    }

    /**
     * Called by the view when a key release event has been registered
     * @param key the key that has been released
     */
    public void onRelease(String key) {
        
        processKey(key);

        if (repeatTask != null) {
            repeatTask.cancel();
            repeatTask = null;
            timer.purge();
        }
        
    }

    /**
     * Handles key presses by either sending the event to the current 
     * InputConnection or by changing the keyboard layout
     * @param key the key to process
     */
    protected void processKey(String key) {
        InputConnection inputConnection = getCurrentInputConnection();

        if ("Delete".equals(key)) {
            sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
        } else if ("Enter".equals(key)) {
            sendDownUpKeyEvents(KeyEvent.KEYCODE_ENTER);
        } else if ("Shift".equals(key)) {
            String[][] keys = view.getKeys();
            if (keys == QUERTY) {
                view.setKeys(CAPS);
            } else if (keys == CAPS) {
                view.setKeys(QUERTY);
            } else if (keys == SYMBOLS) {
                view.setKeys(CAPITAL_SYMBOLS);
            } else if (keys == CAPITAL_SYMBOLS) {
                view.setKeys(SYMBOLS);
            }
        } else if ("123".equals(key)) {
            String[][] keys = view.getKeys();
            if (keys == QUERTY) {
                view.setKeys(SYMBOLS);
            } else if (keys == CAPS) {
                view.setKeys(CAPITAL_SYMBOLS);
            }
        } else if ("ABC".equals(key)) {
            String[][] keys = view.getKeys();
            if (keys == SYMBOLS) {
                view.setKeys(QUERTY);
            } else if (keys == CAPITAL_SYMBOLS) {
                view.setKeys(CAPS);
            }
        } else if ("Space".equals(key)) {
            inputConnection.commitText(" ", 1);
        } else {
            inputConnection.commitText(key, 1);
        }
    }
}
